﻿using System;
using System.Linq;
using System.Collections.Generic;
using OfficeOpenXml;
using System.Text.RegularExpressions;

namespace documentRdr
{
    public static class DataProcessing
    {
        public static string GetDistrict(ExcelRangeBase cell)
        {
            var columnLetter = LetterBetweenNumber.Match(cell.Address).Groups["ColumnLetter"].Value;
            if (columnLetter != "C" && columnLetter != "B")
                throw new Exception("Колонка переданной не имеет идентификатора С");

            return
                Districts
                .Values
                .Select((districtName, index) => new { districtName, index })
                .FirstOrDefault(district => cell.Offset(0, district.index + 1).Value != null)
                .IfNotNull(d=>d.districtName);

        }
        public static bool IsSquareMatches(string description,int area,int variation)
        {
            var ranges =
                BoundsRegex.Matches(description)
                .Cast<Match>()
                .Select(m => new { firstBound = int.Parse(m.Groups["FirstBound"].Value), secondBound = int.Parse(m.Groups["SecondBound"].Value) });

            if (ranges.Any(r => area >= r.firstBound - variation && area <= r.secondBound + variation))
                return true;

            var allNumbers =
            NumberRegex.Matches(description)
                .Cast<Match>()
                .Select(m => int.Parse(m.Value));

            return allNumbers
                .Except(ranges.Select(r => new[] { r.firstBound, r.secondBound }).SelectMany(r => r))
                .Any(a => area >= a - variation && area <= a + variation);
        }

        public static readonly Regex NumberRegex = new Regex(@"\d+", RegexOptions.Compiled);
        private static readonly Regex LetterBetweenNumber = new Regex(@"(?:\A|^)\d*(?<ColumnLetter>[a-zA-Z]+)\d*", RegexOptions.Compiled);
        private static readonly Dictionary<char, string> Districts = new Dictionary<char, string>
                                                                   {
                                                                       {'D',"САО"},
                                                                       {'E',"СВАО"},
                                                                       {'F',"ВАО"},
                                                                       {'G',"ЮВАО"},
                                                                       {'H',"ЮАО"},
                                                                       {'I',"ЮЗАО"},
                                                                       {'J',"ЗАО"},
                                                                       {'K',"СЗАО"},
                                                                       {'L',"ЦАО"},
                                                                   };

        public static readonly Regex FoodRegex = new Regex(@"(?:Кафе|Ресторан|Бар|Стол|Коф|Пиц|Общепит)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly Regex ShopRegex = new Regex(@"(?:Магаз|Аптек|Отдел|Пиво|Торгов)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly Regex OfficeRegex = new Regex(@"(?:Офис|Делов|Центр)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly Regex DiscoRegex = new Regex(@"(?:Бильярд|Игров|Танц|Диско)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly Regex HouseKeepingRegex = new Regex(@"(?:Ателье|Ремонт|Одежд|Обув)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly Regex FactoryRegex = new Regex(@"(?:Склад|Производств)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly Regex BeautyRegex = new Regex(@"(?:Парик|Салон|Солярий|Маникюр)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly Regex BoundsRegex = new Regex(@"(?<FirstBound>\d+)\s*[-]\s*(?<SecondBound>\d+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    }
    public static class ProceedData
    {
        public static T IfNotNull<T, U>(this U item, Func<U, T> lambda) where U : class
        {
            return item == null ? default(T) : lambda(item);
        }
        public static T Unless<T>(this T item, Func<T, bool> lambda) where T : class
        {
            return item == null ? default(T) : lambda(item) ? item : default(T);
        }
        public static T If<T>(this T item, Func<T, bool> evaluator) where T : class
        {
            return item == null ? default(T) : evaluator(item) ? item : default(T);
        }
        public static T Proceed<T>(this T item, Action<T> action) where T : class
        {
            if (item == null)
                return default(T);
            action(item);
            return item;
        }
    }
}